package com.djf.djfpgsql.wrapper.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.djf.djfpgsql.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

/**
 * 纯Wrapper方式的Mapper接口
 * 主要依赖BaseMapper提供的基础CRUD方法
 * 只在Wrapper无法满足需求时才添加自定义SQL
 */
@Mapper
public interface UserWrapperMapper extends BaseMapper<User> {
    
    /*
     * 注意：大部分操作都通过BaseMapper + Wrapper完成
     * 这里只定义Wrapper无法处理的复杂查询
     * 
     * BaseMapper提供的方法（完全兼容MySQL和PostgreSQL）：
     * - insert(T entity)
     * - deleteById(Serializable id)
     * - delete(Wrapper<T> wrapper)
     * - updateById(T entity)
     * - update(T entity, Wrapper<T> wrapper)
     * - selectById(Serializable id)
     * - selectList(Wrapper<T> wrapper)
     * - selectCount(Wrapper<T> wrapper)
     * - selectMaps(Wrapper<T> wrapper)
     * - selectPage(IPage<T> page, Wrapper<T> wrapper)
     */
    
    // ==================== 数据库特定的复杂查询 ====================
    
    /**
     * 全文搜索 - MySQL版本
     * 使用MySQL的FULLTEXT索引功能
     * 注意：需要在表上创建FULLTEXT索引
     */
    @Select("SELECT * FROM users WHERE MATCH(name, email) AGAINST(#{keyword} IN NATURAL LANGUAGE MODE)")
    List<User> fullTextSearchMySQL(@Param("keyword") String keyword);
    
    /**
     * 全文搜索 - PostgreSQL版本
     * 使用PostgreSQL的全文搜索功能
     * 注意：需要安装中文分词扩展（如zhparser）
     */
    @Select("SELECT * FROM users WHERE to_tsvector('simple', name || ' ' || email) @@ plainto_tsquery('simple', #{keyword})")
    List<User> fullTextSearchPGSQL(@Param("keyword") String keyword);
    
    /**
     * 正则表达式查询 - MySQL版本
     * 使用MySQL的REGEXP操作符
     */
    @Select("SELECT * FROM users WHERE name REGEXP #{pattern}")
    List<User> regexSearchMySQL(@Param("pattern") String pattern);
    
    /**
     * 正则表达式查询 - PostgreSQL版本
     * 使用PostgreSQL的~操作符
     */
    @Select("SELECT * FROM users WHERE name ~ #{pattern}")
    List<User> regexSearchPGSQL(@Param("pattern") String pattern);
    
    /**
     * JSON聚合查询 - MySQL版本
     * 使用MySQL的JSON函数进行复杂聚合
     */
    @Select("SELECT JSON_EXTRACT(profile, '$.city') as city, COUNT(*) as user_count " +
            "FROM users " +
            "WHERE profile IS NOT NULL " +
            "GROUP BY JSON_EXTRACT(profile, '$.city') " +
            "ORDER BY user_count DESC")
    List<Map<String, Object>> getJsonAggregationMySQL();
    
    /**
     * JSON聚合查询 - PostgreSQL版本
     * 使用PostgreSQL的JSON操作符进行复杂聚合
     */
    @Select("SELECT profile->>'city' as city, COUNT(*) as user_count " +
            "FROM users " +
            "WHERE profile IS NOT NULL " +
            "GROUP BY profile->>'city' " +
            "ORDER BY user_count DESC")
    List<Map<String, Object>> getJsonAggregationPGSQL();
    
    /**
     * 窗口函数查询 - MySQL版本（MySQL 8.0+）
     * 计算每个用户在其年龄组中的余额排名
     */
    @Select("SELECT id, name, age, balance, " +
            "RANK() OVER (PARTITION BY FLOOR(age/10)*10 ORDER BY balance DESC) as balance_rank " +
            "FROM users " +
            "ORDER BY age, balance_rank")
    List<Map<String, Object>> getBalanceRankingMySQL();
    
    /**
     * 窗口函数查询 - PostgreSQL版本
     * 计算每个用户在其年龄组中的余额排名
     */
    @Select("SELECT id, name, age, balance, " +
            "RANK() OVER (PARTITION BY (age/10)*10 ORDER BY balance DESC) as balance_rank " +
            "FROM users " +
            "ORDER BY age, balance_rank")
    List<Map<String, Object>> getBalanceRankingPGSQL();
    
    /**
     * 递归查询 - MySQL版本（MySQL 8.0+）
     * 假设用户表有parent_id字段，查询用户的所有下级
     */
    @Select("WITH RECURSIVE user_hierarchy AS ( " +
            "  SELECT id, name, parent_id, 1 as level " +
            "  FROM users " +
            "  WHERE id = #{userId} " +
            "  UNION ALL " +
            "  SELECT u.id, u.name, u.parent_id, uh.level + 1 " +
            "  FROM users u " +
            "  INNER JOIN user_hierarchy uh ON u.parent_id = uh.id " +
            ") " +
            "SELECT * FROM user_hierarchy ORDER BY level, id")
    List<Map<String, Object>> getUserHierarchyMySQL(@Param("userId") Long userId);
    
    /**
     * 递归查询 - PostgreSQL版本
     * 假设用户表有parent_id字段，查询用户的所有下级
     */
    @Select("WITH RECURSIVE user_hierarchy AS ( " +
            "  SELECT id, name, parent_id, 1 as level " +
            "  FROM users " +
            "  WHERE id = #{userId} " +
            "  UNION ALL " +
            "  SELECT u.id, u.name, u.parent_id, uh.level + 1 " +
            "  FROM users u " +
            "  INNER JOIN user_hierarchy uh ON u.parent_id = uh.id " +
            ") " +
            "SELECT * FROM user_hierarchy ORDER BY level, id")
    List<Map<String, Object>> getUserHierarchyPGSQL(@Param("userId") Long userId);
    
    /**
     * 地理位置查询 - MySQL版本
     * 使用MySQL的空间函数（需要MySQL 5.7+）
     */
    @Select("SELECT id, name, " +
            "ST_Distance_Sphere(POINT(#{longitude}, #{latitude}), POINT(longitude, latitude)) as distance " +
            "FROM users " +
            "WHERE longitude IS NOT NULL AND latitude IS NOT NULL " +
            "HAVING distance <= #{radius} " +
            "ORDER BY distance")
    List<Map<String, Object>> getNearbyUsersMySQL(
        @Param("longitude") Double longitude, 
        @Param("latitude") Double latitude, 
        @Param("radius") Double radius);
    
    /**
     * 地理位置查询 - PostgreSQL版本
     * 使用PostgreSQL的PostGIS扩展
     */
    @Select("SELECT id, name, " +
            "ST_Distance(ST_Point(#{longitude}, #{latitude})::geography, ST_Point(longitude, latitude)::geography) as distance " +
            "FROM users " +
            "WHERE longitude IS NOT NULL AND latitude IS NOT NULL " +
            "AND ST_DWithin(ST_Point(#{longitude}, #{latitude})::geography, ST_Point(longitude, latitude)::geography, #{radius}) " +
            "ORDER BY distance")
    List<Map<String, Object>> getNearbyUsersPGSQL(
        @Param("longitude") Double longitude, 
        @Param("latitude") Double latitude, 
        @Param("radius") Double radius);
    
    /**
     * 数组操作查询 - MySQL版本
     * 使用MySQL的JSON数组函数
     */
    @Select("SELECT * FROM users " +
            "WHERE JSON_CONTAINS(tags, JSON_QUOTE(#{tag}))")
    List<User> getUsersByTagMySQL(@Param("tag") String tag);
    
    /**
     * 数组操作查询 - PostgreSQL版本
     * 使用PostgreSQL的数组操作符
     */
    @Select("SELECT * FROM users " +
            "WHERE tags @> ARRAY[#{tag}]::text[]")
    List<User> getUsersByTagPGSQL(@Param("tag") String tag);
    
    /**
     * 时间序列分析 - MySQL版本
     * 按小时统计用户注册数量
     */
    @Select("SELECT " +
            "DATE_FORMAT(created_at, '%Y-%m-%d %H:00:00') as hour_slot, " +
            "COUNT(*) as registration_count " +
            "FROM users " +
            "WHERE created_at >= DATE_SUB(NOW(), INTERVAL #{days} DAY) " +
            "GROUP BY DATE_FORMAT(created_at, '%Y-%m-%d %H:00:00') " +
            "ORDER BY hour_slot")
    List<Map<String, Object>> getRegistrationTimeSeriesMySQL(@Param("days") Integer days);
    
    /**
     * 时间序列分析 - PostgreSQL版本
     * 按小时统计用户注册数量
     */
    @Select("SELECT " +
            "DATE_TRUNC('hour', created_at) as hour_slot, " +
            "COUNT(*) as registration_count " +
            "FROM users " +
            "WHERE created_at >= NOW() - INTERVAL '#{days} days' " +
            "GROUP BY DATE_TRUNC('hour', created_at) " +
            "ORDER BY hour_slot")
    List<Map<String, Object>> getRegistrationTimeSeriesPGSQL(@Param("days") Integer days);
}

/*
 * Wrapper方式的Mapper设计原则：
 * 
 * 1. 最小化自定义SQL：
 *    - 优先使用BaseMapper + Wrapper
 *    - 只在必要时添加自定义方法
 * 
 * 2. 数据库特定功能：
 *    - 全文搜索
 *    - 正则表达式
 *    - JSON复杂操作
 *    - 窗口函数
 *    - 递归查询
 *    - 地理位置计算
 *    - 数组操作
 *    - 时间序列分析
 * 
 * 3. 命名规范：
 *    - 方法名体现功能和数据库类型
 *    - 参数使用@Param注解
 * 
 * 4. 注释说明：
 *    - 说明使用的数据库特性
 *    - 标注依赖的扩展或版本
 * 
 * 5. 返回类型：
 *    - 简单查询返回实体类
 *    - 复杂查询返回Map
 */